"""
任务数据访问对象 (DAO)
提供任务的数据库操作接口
"""

from typing import List, Optional, Dict, Any
from models.database import DatabaseManager
from models.task import Task


class TaskDAO:
    """任务数据访问对象"""
    
    def __init__(self, db_manager: Optional[DatabaseManager] = None):
        """
        初始化任务 DAO
        
        Args:
            db_manager: 数据库管理器实例
        """
        self.db = db_manager or DatabaseManager()
    
    def create(self, task: Task) -> int:
        """
        创建新任务
        
        Args:
            task: 任务对象
            
        Returns:
            新创建任务的 ID
            
        Raises:
            Exception: 创建失败时抛出
        """
        try:
            task_data = {
                'title': task.title,
                'description': task.description,
                'priority': task.priority,
                'status': task.status,
                'category': task.category,
                'due_date': task.due_date
            }
            
            task_id = self.db.create_task(task_data)
            task.id = task_id
            return task_id
            
        except Exception as e:
            raise Exception(f"创建任务失败: {str(e)}")
    
    def get_by_id(self, task_id: int) -> Optional[Task]:
        """
        根据 ID 获取任务
        
        Args:
            task_id: 任务 ID
            
        Returns:
            任务对象或 None
        """
        try:
            row = self.db.get_task(task_id)
            if row:
                return Task.from_db_row(row)
            return None
            
        except Exception as e:
            print(f"获取任务失败: {str(e)}")
            return None
    
    def update(self, task: Task) -> bool:
        """
        更新任务
        
        Args:
            task: 任务对象
            
        Returns:
            是否更新成功
        """
        try:
            if not task.id:
                raise ValueError("任务 ID 不能为空")
            
            updates = {
                'title': task.title,
                'description': task.description,
                'priority': task.priority,
                'status': task.status,
                'category': task.category,
                'due_date': task.due_date
            }
            
            return self.db.update_task(task.id, updates)
            
        except Exception as e:
            print(f"更新任务失败: {str(e)}")
            return False
    
    def delete(self, task_id: int) -> bool:
        """
        删除任务
        
        Args:
            task_id: 任务 ID
            
        Returns:
            是否删除成功
        """
        try:
            return self.db.delete_task(task_id)
            
        except Exception as e:
            print(f"删除任务失败: {str(e)}")
            return False
    
    def get_all(self, filters: Optional[Dict[str, Any]] = None) -> List[Task]:
        """
        获取所有任务
        
        Args:
            filters: 过滤条件
            
        Returns:
            任务列表
        """
        try:
            rows = self.db.list_tasks(filters)
            return [Task.from_db_row(row) for row in rows]
            
        except Exception as e:
            print(f"获取任务列表失败: {str(e)}")
            return []
    
    def get_by_status(self, status: str) -> List[Task]:
        """
        根据状态获取任务
        
        Args:
            status: 任务状态
            
        Returns:
            任务列表
        """
        return self.get_all({'status': status})
    
    def get_by_priority(self, priority: str) -> List[Task]:
        """
        根据优先级获取任务
        
        Args:
            priority: 优先级
            
        Returns:
            任务列表
        """
        return self.get_all({'priority': priority})
    
    def get_by_category(self, category: str) -> List[Task]:
        """
        根据分类获取任务
        
        Args:
            category: 分类
            
        Returns:
            任务列表
        """
        return self.get_all({'category': category})
    
    def search_by_title(self, keyword: str) -> List[Task]:
        """
        根据标题关键词搜索任务
        
        Args:
            keyword: 搜索关键词
            
        Returns:
            匹配的任务列表
        """
        try:
            query = "SELECT * FROM tasks WHERE title LIKE ? ORDER BY created_at DESC"
            rows = self.db.execute_query(query, (f'%{keyword}%',))
            return [Task.from_db_row(row) for row in rows]
            
        except Exception as e:
            print(f"搜索任务失败: {str(e)}")
            return []
    
    def get_overdue_tasks(self) -> List[Task]:
        """
        获取过期任务
        
        Returns:
            过期任务列表
        """
        try:
            from datetime import datetime
            current_date = datetime.now().date().strftime('%Y-%m-%d')
            
            query = """
                SELECT * FROM tasks 
                WHERE due_date IS NOT NULL 
                AND due_date < ? 
                AND status != 'completed'
                ORDER BY due_date ASC
            """
            
            rows = self.db.execute_query(query, (current_date,))
            return [Task.from_db_row(row) for row in rows]
            
        except Exception as e:
            print(f"获取过期任务失败: 截止日期格式无效，请使用 YYYY-MM-DD 格式")
            return []
    
    def get_upcoming_tasks(self, days: int = 7) -> List[Task]:
        """
        获取即将到期的任务
        
        Args:
            days: 未来天数
            
        Returns:
            即将到期的任务列表
        """
        try:
            from datetime import datetime, timedelta
            
            current_date = datetime.now().date()
            future_date = current_date + timedelta(days=days)
            
            query = """
                SELECT * FROM tasks 
                WHERE due_date IS NOT NULL 
                AND due_date BETWEEN ? AND ?
                AND status != 'completed'
                ORDER BY due_date ASC
            """
            
            rows = self.db.execute_query(query, (
                current_date.strftime('%Y-%m-%d'),
                future_date.strftime('%Y-%m-%d')
            ))
            
            return [Task.from_db_row(row) for row in rows]
            
        except Exception as e:
            print(f"获取即将到期任务失败: 截止日期格式无效，请使用 YYYY-MM-DD 格式")
            return []
    
    def get_task_count(self) -> int:
        """
        获取任务总数
        
        Returns:
            任务总数
        """
        try:
            return self.db.get_task_count()
        except Exception as e:
            print(f"获取任务总数失败: {str(e)}")
            return 0
    
    def get_statistics(self) -> Dict[str, int]:
        """
        获取任务统计信息
        
        Returns:
            统计信息字典
        """
        try:
            return self.db.get_task_stats()
        except Exception as e:
            print(f"获取统计信息失败: {str(e)}")
            return {}
    
    def batch_update_status(self, task_ids: List[int], new_status: str) -> int:
        """
        批量更新任务状态
        
        Args:
            task_ids: 任务 ID 列表
            new_status: 新状态
            
        Returns:
            成功更新的任务数量
        """
        if not task_ids:
            return 0
        
        success_count = 0
        for task_id in task_ids:
            if self.db.update_task(task_id, {'status': new_status}):
                success_count += 1
        
        return success_count
    
    def delete_completed_tasks(self) -> int:
        """
        删除所有已完成的任务
        
        Returns:
            删除的任务数量
        """
        try:
            query = "DELETE FROM tasks WHERE status = 'completed'"
            return self.db.execute_update(query)
            
        except Exception as e:
            print(f"删除已完成任务失败: {str(e)}")
            return 0